//
//  ViewController.swift
//  01- 视频采集
//
//  Created by 我演示 on 2019/11/13.
//  Copyright © 2019 ALLSall. All rights reserved.
//

import UIKit
import AVFoundation

class ViewController: UIViewController {
    
    
    fileprivate lazy var session : AVCaptureSession = AVCaptureSession()
    

    fileprivate var videoOutput : AVCaptureVideoDataOutput?
    
    // 需要再终止的时候，移除对应的预览图层
    fileprivate var prewviewLayer : AVCaptureVideoPreviewLayer?
    
    ///开启前置摄像头
    fileprivate var videoInput : AVCaptureDeviceInput?
    //4: 录制文件
    fileprivate var movieOutPut : AVCaptureMovieFileOutput?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        self.view.backgroundColor = UIColor.white
        //1: 初始化饮输入输出
        
        let btn = UIButton.init()
        btn.frame = CGRect.init(x: 100, y: 100, width: 100, height: 30)
        btn.backgroundColor = UIColor.red
        btn.setTitle("开始采集", for: .normal)
        btn.setTitleColor(.white, for: .normal)
        btn.addTarget(self, action: #selector(startActions), for: .touchUpInside)
        self.view.addSubview(btn)
        
        
        let btn2 = UIButton.init()
        btn2.frame = CGRect.init(x: 100, y: 180, width: 100, height: 30)
        btn2.backgroundColor = UIColor.red
        btn2.setTitle("停止采集", for: .normal)
        btn2.setTitleColor(.white, for: .normal)
        btn2.addTarget(self, action: #selector(endAciton), for: .touchUpInside)
        self.view.addSubview(btn2)
        
        let btn3 = UIButton.init()
        btn3.frame = CGRect.init(x: 100, y: 250, width: 100, height: 30)
        btn3.backgroundColor = UIColor.red
        btn3.setTitle("切换信息", for: .normal)
        btn3.setTitleColor(.white, for: .normal)
        btn3.addTarget(self, action: #selector(rotateCamera), for: .touchUpInside)
        self.view.addSubview(btn3)
        
        
        //初始化音频的输入输出
        
        setUpVideoInputOutput()
        //  初始化音视频的
        setUpAudioInputOutput()
        //3:初始化预览图层
        setUpPreviewLayer()
        //4: 录制文件，并且写入文件
        setupMovieFileOutput()
    }

    // 开始写入
    @objc func startActions () {
            session.startRunning()
             view.layer.insertSublayer((prewviewLayer!), at: 0)

    }
    
    /// 停止写入
    @objc func endAciton () {
        movieOutPut!.stopRecording()
        session.stopRunning()
        prewviewLayer?.removeFromSuperlayer()
        
    }
  
    
    @objc func rotateCamera() {
        // 1: 取出之前镜头的方向
        

        guard let videoInputs = videoInput else {return}
        let poritation: AVCaptureDevice.Position = videoInputs.device.position == .front  ?  AVCaptureDevice.Position.back : .front
        
        //2: 创建蛇形头
        guard    let devices = AVCaptureDevice.devices() as? [AVCaptureDevice] else {return}
        guard let device = devices.filter({$0.position ==  poritation}).first else {return}
        
        
        //        device.delega
        guard let newInput = try? AVCaptureDeviceInput(device: device) else {return}
        
        
        //4: 移除之前的input ，添加新的input
        session.beginConfiguration()
        session.removeInput(videoInputs)
        
        if session.canAddInput(newInput) {
            session.addInput(newInput)
        }
        
        session.commitConfiguration()
        self.videoInput = newInput
        
    }
    
    fileprivate func setupMovieFileOutput() {
        //1: 创建写入文件的输出
        let fileOutput = AVCaptureMovieFileOutput()
        self.movieOutPut = fileOutput
        //1.1
           let connection = fileOutput.connection(with: AVMediaType.video)
        connection?.automaticallyAdjustsVideoMirroring = true
        
        ///1/3 写入对应的文件
        if session.canAddOutput(fileOutput) {
            session.addOutput(fileOutput)
        }
        
        //2: 直接开始写入文件
        let filePath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first! + "abc.mp4"
        let fileUrl = URL(fileURLWithPath: filePath)
        fileOutput.startRecording(to: fileUrl, recordingDelegate: self)
        
    }
    
    
}
// MARK- 通过代理监听x，开始写入文件
extension ViewController : AVCaptureFileOutputRecordingDelegate {

    
    func fileOutput(_ output: AVCaptureFileOutput, didStartRecordingTo fileURL: URL, from connections: [AVCaptureConnection]) {
        print("结束")
    }
    
    func fileOutput(_ output: AVCaptureFileOutput, didFinishRecordingTo outputFileURL: URL, from connections: [AVCaptureConnection], error: Error?) {
        print("结束写入")
    }
    
}


extension ViewController {
    fileprivate func setUpVideoInputOutput () {
        //1 : 添加音视频的输入
        guard    let devices = AVCaptureDevice.devices() as? [AVCaptureDevice] else {return}
        guard let device = devices.filter({$0.position == .front}).first else {return}
        
//        device.delega
        guard let input = try? AVCaptureDeviceInput(device: device) else {return}
        self.videoInput = input
        //2: 添加音视频的输出
  
        
        let output = AVCaptureVideoDataOutput()
        //4: 子队列处理
        let queue = DispatchQueue.global()
        output.setSampleBufferDelegate(self, queue: queue)
        self.videoOutput = output
          
        
        //3: 添加输入输出
             // 添加输入输出
        addInputOutToSession(input, output)
        
    }
    
    fileprivate func setUpAudioInputOutput () {
        
        guard let device = AVCaptureDevice.default(for: AVMediaType.audio) else {return}
        
       guard let input = try? AVCaptureDeviceInput(device: device   ) else {return}
         
        //2 : 创建输出
        let output = AVCaptureAudioDataOutput()
        
        let queue = DispatchQueue.global()
        
        output.setSampleBufferDelegate(self, queue: queue)
        
        // 添加输入输出
        addInputOutToSession(input, output)
  
        
       }
    
    
    private func addInputOutToSession (_ input : AVCaptureInput , _ output : AVCaptureOutput){
        //3: 添加输入输出
          session.beginConfiguration()
          if session.canAddInput(input) {
              session.addInput(input)
          }else {
              
          }
          if session.canAddOutput(output) {
              
          }
          session.commitConfiguration()
    }
    
    
    // 预览
    fileprivate func setUpPreviewLayer () {
        
        //1: 创建浏览图层
  let previewLayer = AVCaptureVideoPreviewLayer(session: session) 
        
        //2: 设置previewLayer 属性
        previewLayer.frame = view.bounds
        
        //3: 将图层添加到控制器的view 的layer
//        view.layer.addSublayer(previewLayer) 这一句代码会产生覆盖
        view.layer.insertSublayer(previewLayer, at: 0)
        self.prewviewLayer = previewLayer
    }
          
    
}


extension ViewController : AVCaptureVideoDataOutputSampleBufferDelegate ,AVCaptureAudioDataOutputSampleBufferDelegate{
    func captureOutput(_ output: AVCaptureOutput, didDrop sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
        
    }
    
    ///  采集到一帧画面
    func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
        
        if videoOutput?.connection(with: .video) == connection {
            print("采集到的")
        }else{
            print("擦剂到视频")
            
        }
    }
    
}
